﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
using IndexMarkSilverlightClient.Classes;
using IndexMarkSilverlightClient.IndexMarkServiceReference;
using System.Windows.Browser;

namespace IndexMarkSilverlightClient.Views.Controls.ReportsControls
{
    public partial class USTUTreeView2: UserControl, INotifyPropertyChanged
    {
        public delegate void LoadStartingHandler();
        public delegate void LoadCompletedHandler();
        public delegate void LoadFailedHandler(Exception error);

        public event LoadStartingHandler LoadStarting;
        public event LoadCompletedHandler LoadCompleted;
        public event LoadFailedHandler LoadFailed;

        IndexMarkServiceClient client = new IndexMarkServiceClient();

        public IEnumerable<Respondent> Teahers
        {
            get
            {
                return selectedRespondents;
            }
        }
        private List<HierarchicalSource> source = new List<HierarchicalSource>();
        private List<Respondent> selectedRespondents = new List<Respondent>();

        private int iDTerm;
        
        public int IDTerm 
        {
            get
            {
                return iDTerm;
            }
            set
            {
                iDTerm = value;
                //LoadTree();
            }
        }

        public bool Check { get; set; }
    
        public void LoadTree()
        {
            RaiseLoadDataStarting();
            client.GetUSTUTreeAsync(iDTerm, Check);
        }
        
        public USTUTreeView2()
        {
            InitializeComponent();
            client.GetUSTUTreeCompleted += new EventHandler<GetUSTUTreeCompletedEventArgs>(client_GetUSTUTreeCompleted);
        }

        void client_GetUSTUTreeCompleted(object sender, GetUSTUTreeCompletedEventArgs e)
        {
            source = CreateSource(e.Result.Cast<DTOBase>());
            this.DataContext = source;

            if (e.Error == null)
                RaiseLoadDataCompleted();
            else
                RaiseLoadDataFailed(e.Error);
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            CheckBox checkBox = sender as CheckBox;

            if (checkBox.Content is Respondent)
            {
                if (checkBox.IsChecked == true)
                    selectedRespondents.Add(checkBox.Content as Respondent);
                else
                    selectedRespondents.Remove(checkBox.Content as Respondent);
            }
        }

        private void PropertyChangedInit(String PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }

        private void RaiseLoadDataStarting()
        {
            if (LoadStarting != null)
            {
                LoadStarting();
            }
        }

        private void RaiseLoadDataCompleted()
        {
            if (LoadCompleted != null)
            {
                LoadCompleted();
            }
        }

        private void RaiseLoadDataFailed(Exception error)
        {
            if (LoadFailed != null)
            {
                LoadFailed(error);
            }
        }

        public void CheckRespondents(IEnumerable<Respondent> respondents)
        {
            foreach (HierarchicalSource s in source)
            {
                _CheckRespondents(respondents, s);
            }
        }

        private void _CheckRespondents(IEnumerable<Respondent> respondents, HierarchicalSource s)
        {
            foreach (HierarchicalSource el in s.Children)
            {
                if (el.Content is Department)
                {
                    _CheckRespondents(respondents, el);
                }
                if (el.Content is Respondent)
                {
                    Respondent tmp = respondents.SingleOrDefault(x => x.IDRespondent == ((Respondent)el.Content).IDRespondent);
                    if (tmp != null)
                    {
                        el.IsChecked = true;
                        if (selectedRespondents.Contains(tmp) == false)
                        {
                            selectedRespondents.Add(tmp);
                        }
                    }
                }
            }
        }

        private List<HierarchicalSource> CreateSource(IEnumerable<DTOBase> elements, HierarchicalSource parent = null)
        {
            List<HierarchicalSource> source = new List<HierarchicalSource>();

            foreach (DTOBase el in elements)
            {
                HierarchicalSource tmp = new HierarchicalSource()
                {
                    Content = el,
                    IsChecked = false,
                    Parent = parent,
                    Children = new List<HierarchicalSource>()
                };
                if (el is DTOChilds)
                {
                    tmp.Children.AddRange(CreateSource((el as DTOChilds).Childs, tmp));
                }
                source.Add(tmp);
            }

            return source;
        }
    }

    /// <summary>
    /// Hierarchical source
    /// </summary>
    public class HierarchicalSource : INotifyPropertyChanged
    {
        private bool? isChecked;
        private static HierarchicalSource firstInstance = null;

        /// <summary>
        /// AfterChecked event to do some extra task after check
        /// </summary>
        public event EventHandler AfterChecked;

        /// <summary>
        /// Gets or sets parent
        /// </summary>
        public HierarchicalSource Parent { get; set; }

        /// <summary>
        /// Gets or sets name
        /// </summary>
        public object Content { get; set; }

        /// <summary>
        /// Gets or sets byPass field
        /// </summary>
        public static bool byPass = false;

        /// <summary>
        /// Gets or sets IsChecked
        /// </summary>
        public bool? IsChecked
        {
            get
            {
                return isChecked;
            }
            set
            {
                if (isChecked != value)
                {
                    isChecked = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
                    }

                    if (Children != null && IsChecked.HasValue)
                    {
                        byPass = true;
                        if (firstInstance == null)
                        {
                            firstInstance = this;
                        }
                        Children.ForEach(x => x.IsChecked = IsChecked.Value);
                        if (ReferenceEquals(this, firstInstance))
                        {
                            byPass = false;
                            firstInstance = null;
                        }
                    }
                    if (byPass)
                    {
                        return;
                    }
                    if (Parent != null)
                    {
                        if (Parent.Children.All(x => x.IsChecked == true))
                        {
                            Parent.IsChecked = true;
                        }
                        else if (Parent.Children.All(x => x.IsChecked == false))
                        {
                            Parent.IsChecked = false;
                        }
                        else
                        {
                            Parent.IsChecked = null;
                        }
                    }
                    if (AfterChecked != null)
                    {
                        AfterChecked(this, EventArgs.Empty);
                    }
                }
            }
        }
        public List<HierarchicalSource> Children { get; set; }

        public HierarchicalSource()
        {
            isChecked = false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
